package com.qding.park.manager.service.queue.biz;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.qding.park.common.core.exceptions.BaseException;
import com.qding.park.common.core.exceptions.business.adapter.AdapterException;
import com.qding.park.common.core.exceptions.business.manager.adapterfactory.AdapterProxyCreateFail;
import com.qding.park.common.utils.OrderNumUtil;
import com.qding.park.manager.adapter.factory.AdapterParkProxyFactory;
import com.qding.park.manager.cache.ConfigDataCacheInter;
import com.qding.park.manager.payment.PaymentInterfaceServiec;
import com.qding.park.manager.pojo.TbFeetrade;
import com.qding.park.manager.pojo.TbParkspace;
import com.qding.park.manager.pojo.TbReserve;
import com.qding.park.manager.pojo.TbUserInfo;
import com.qding.park.manager.pojo.ap.ApReservationInReminder;
import com.qding.park.manager.pojo.ap.ApReserveOrder;
import com.qding.park.manager.pojo.enums.OrderServiceType;
import com.qding.park.manager.pojo.enums.RecordStatusEnum;
import com.qding.park.manager.pojo.enums.ReserverStatusEnum;
import com.qding.park.manager.service.queue.mapper.TbCarMapper;
import com.qding.park.manager.service.queue.mapper.TbFeetradeMapper;
import com.qding.park.manager.service.queue.mapper.TbParkspaceMapper;
import com.qding.park.manager.service.queue.mapper.TbReserveMapper;
import com.qding.park.manager.service.queue.mapper.TbUserInfoMapper;
import com.qding.park.manager.sms.SmsInterfaceServiec;
import com.qding.park.target.common.adapter.ReserveAdapter;

@Component("reserveBiz")
public class ReserveBiz {
    
    private static final Log _log = LogFactory.getLog(ReserveBiz.class);
    @Autowired
    private TbReserveMapper tbReserveMapper;

    
    @Autowired
    private TbCarMapper  tbCarMapper;
    
    @Autowired
    private TbUserInfoMapper tbUserInfoMapper;

    @Autowired
    private TbParkspaceMapper tbParkspaceMapper;

    @Autowired
    private AdapterParkProxyFactory adapterParkProxyFactory;
    
    @Autowired
    private SmsInterfaceServiec smsInterfaceServiec;
    
    @Autowired
    private ConfigDataCacheInter configDataCacheInter;
    
    @Autowired
    private TbFeetradeMapper tbFeetradeMapper;
    
    @Autowired
    private PaymentInterfaceServiec paymentInterfaceServiec;
    
    public void reserveDelayTimeOut(TbReserve reserve) throws BaseException {
        String id = reserve.getId();
        int userId = reserve.getUserID();
        int num = tbReserveMapper.updateStatusTimeout(id, ReserverStatusEnum.RESERVER_DELAY_TIMEOUT.getStatus());

        if (num == 0) {
            _log.error("id:" + id + " 数据不一致性");
            return;
        }
        TbUserInfo tbuserinfo = tbUserInfoMapper.userInfoById(userId);

        /****** 下发取消息预定单 ****************/
        TbParkspace tbParkspace = tbParkspaceMapper.queryParkInfoByParkId(reserve.getParkID());
        int supplierId = tbParkspace.getSupplierId();
        String parkCode = tbParkspace.getParkCode();
        ReserveAdapter adapterProxy = adapterParkProxyFactory.getReserveAdapter(String.valueOf(supplierId));
        ApReserveOrder apReserveOrder = new ApReserveOrder();
        apReserveOrder.setParkId(parkCode);
        apReserveOrder.setCarNum(reserve.getCarNum());
        apReserveOrder.setStartTime(reserve.getStartTime());
        apReserveOrder.setEndTime(reserve.getEndTime());
        apReserveOrder.setOrderId(id);
        adapterProxy.cancelReserve(apReserveOrder);
        /****** 下发取消息预定单 ****************/

        /****** 向用户发送 预定单延期超时消息 *************/
        smsInterfaceServiec.reserve_timeout_notice(String.valueOf(tbuserinfo.getTel()));
        /****** 向用户发送 预定单延期超时 *************/
    }
    
    @Transactional(rollbackFor = Throwable.class)
    public void carInCheck(ApReservationInReminder apReservationInReminder) throws BaseException {
        // 卡号
        String cardCode = apReservationInReminder.getCardCode();
        // 车牌
        String carNum = apReservationInReminder.getCarNum();
        // 进场时间
        Date inDateTime = apReservationInReminder.getInDateTime();
        // 进场侬岗
        String inRoom = apReservationInReminder.getInRoom();
        // 车场编号
        String parkCode = apReservationInReminder.getParkId();
        // 车场供应闪编号
        String supplyID = apReservationInReminder.getSupplyID();
        TbParkspace tbParkspace = configDataCacheInter.queryParkSpace(parkCode, Integer.valueOf(supplyID));
        int parkId = tbParkspace.getId();
        TbReserve tbReserve = tbReserveMapper.queryReservedByParkCarnum(parkId, carNum);
        
        if(tbReserve==null){
            _log.error("没有找到此预定");
            return ;
        }
        /**** 计算是否超时进场 ********/
        boolean istimout = false;
        String reserveId = tbReserve.getId();
        istimout = new Date().getTime() > tbReserve.getEndTime().getTime() ? true : false;
        /************/

        if (istimout) {
            // 超时进场
            /***************/
            tbReserve.setStatus(ReserverStatusEnum.RESERVER_OVERTIME_INCHECK.getStatus());
            tbReserve.setCheckInTime(inDateTime);
            int num = tbReserveMapper.timeoutIncheck(tbReserve);
            if (num == 0) {
                _log.error("无效的预定:" + tbReserve);
                return;
            }
            /**** 下发取消预定单 ********/
            int supplierId = tbParkspace.getSupplierId();
            ReserveAdapter adapterProxy = adapterParkProxyFactory.getReserveAdapter(String.valueOf(supplierId));
            ApReserveOrder apReserveOrder = new ApReserveOrder();
            apReserveOrder.setParkId(parkCode);
            apReserveOrder.setCarNum(tbReserve.getCarNum());
            apReserveOrder.setStartTime(tbReserve.getStartTime());
            apReserveOrder.setEndTime(tbReserve.getEndTime());
            apReserveOrder.setOrderId(reserveId);
            adapterProxy.cancelReserve(apReserveOrder);
            /**** 下发取消预定单 ********/
        } else {
            // 没有超时
            tbReserve.setStatus(ReserverStatusEnum.RESERVER_INCHECK.getStatus());
            tbReserve.setCheckInTime(inDateTime);
            int num = tbReserveMapper.incheck(tbReserve);

            if (num == 0) {
                _log.error("无效的预定:" + tbReserve);
                return;
            }

            /**** 下发取消预定单 ********/
//          TbParkspace tbParkspace = configDataCacheInter.queryParkSpace(tbReserve.getParkID());
//          String parkCode = tbParkspace.getParkCode();
            int supplierId = tbParkspace.getSupplierId();
            ReserveAdapter adapterProxy = adapterParkProxyFactory.getReserveAdapter(String.valueOf(supplierId));
            ApReserveOrder apReserveOrder = new ApReserveOrder();
            apReserveOrder.setParkId(parkCode);
            apReserveOrder.setCarNum(tbReserve.getCarNum());
            apReserveOrder.setStartTime(tbReserve.getStartTime());
            apReserveOrder.setEndTime(tbReserve.getEndTime());
            apReserveOrder.setOrderId(reserveId);
            adapterProxy.cancelReserve(apReserveOrder);
            /**** 下发取消预定单 ********/

            /**** *此处要调用北京接口 ********/
            // 退款押金
            TbFeetrade tbFeetrade = new TbFeetrade();
            tbFeetrade.setId(OrderNumUtil.getOrderNum(tbReserve.getUserID(),OrderServiceType.FEETRADE.getTag()));
            tbFeetrade.setUserID(tbReserve.getUserID());
            tbFeetrade.setParkID(tbReserve.getParkID());
            tbFeetrade.setFeeType(TbFeetrade.FeeTypeEnum.REFUND_PAY.getType());
            tbFeetrade.setFeeCost(tbReserve.getDeposit());
            tbFeetrade.setBusinessID(tbReserve.getTradeid());
            tbFeetrade.setChannel(TbFeetrade.ChannelEnum.CAPITALFLOW_ONLINE.getType());
            tbFeetrade.setStatus(RecordStatusEnum.EFFICIENCY.getStatus());
            tbFeetradeMapper.save(tbFeetrade);
            /**** 调用北京接口 *****/
            // 没有超时 退还押金
            paymentInterfaceServiec.refundOrder(tbReserve.getId());
            /**** 调用北京接口 *****/
        }

    }
    
    @Transactional(rollbackFor = Throwable.class)
    public void reservePayedHandle(TbReserve tbReserve) throws BaseException {
        TbParkspace tbParkspace = tbParkspaceMapper.queryParkInfoByParkId(tbReserve.getParkID());
        Date now = new Date();
        Date endTime = tbReserve.getEndTime();

        if (now.getTime() > endTime.getTime()) {
            // 已经超时 支付成功下发失败 退款
            tbReserve.setStatus(ReserverStatusEnum.RESERVER_ISSUED_PARKFail.getStatus());
            // 支付成功超时
            int num = tbReserveMapper.timeout_payed(tbReserve);

            if (num == 0) {
                return;
            }
            String carpassId = tbReserve.getBjOrderId();
            paymentInterfaceServiec.refundOrder(carpassId);

        } else {
            tbReserve.setStatus(ReserverStatusEnum.RESERVER_ISSUED_PARKSUCCESS.getStatus());
            // 没有超时
            int num = tbReserveMapper.reservePayedHandle(tbReserve);
            if (num == 0) {
                return;
            }
            /**** 下发预定单 ********/
            ReserveAdapter adapterProxy = adapterParkProxyFactory.getReserveAdapter(String.valueOf(tbParkspace.getSupplierId()));
            ApReserveOrder apReserveOrder = new ApReserveOrder();
            apReserveOrder.setParkId(tbParkspace.getParkCode());
            apReserveOrder.setCarNum(tbReserve.getCarNum());
            apReserveOrder.setStartTime(tbReserve.getStartTime());
            apReserveOrder.setEndTime(tbReserve.getEndTime());
            apReserveOrder.setOrderId(tbReserve.getParkOrderId());
            adapterProxy.reserveParkSpace(apReserveOrder);
            /**** 下发预定单 ********/
        }

    }
    
    @Transactional(rollbackFor = Throwable.class)
    public  void issuedFailRollBack(TbReserve tbReserve){
        tbReserve.setStatus(ReserverStatusEnum.RESERVER_ISSUED_PARKFail.getStatus());
        tbReserveMapper.reserveIssuedFailRollBack(tbReserve);
        
        /**** *此处要调用北京接口 ********/
        // 退款押金
        TbFeetrade tbFeetrade = new TbFeetrade();
        tbFeetrade.setId(OrderNumUtil.getOrderNum(tbReserve.getUserID(),OrderServiceType.FEETRADE.getTag()));
        tbFeetrade.setUserID(tbReserve.getUserID());
        tbFeetrade.setParkID(tbReserve.getParkID());
        tbFeetrade.setFeeType(TbFeetrade.FeeTypeEnum.REFUND_PAY.getType());
        tbFeetrade.setFeeCost(tbReserve.getRealPayDeposit());
        tbFeetrade.setBusinessID(tbReserve.getId());
        tbFeetrade.setChannel(TbFeetrade.ChannelEnum.CAPITALFLOW_ONLINE.getType());
        tbFeetrade.setStatus(RecordStatusEnum.EFFICIENCY.getStatus());
        tbFeetradeMapper.save(tbFeetrade);
        /**** 调用北京接口 *****/
        // 没有超时 退还押金
        paymentInterfaceServiec.refundOrder(tbReserve.getBjOrderId());
        /**** 调用北京接口 *****/
    }

    @Transactional(rollbackFor = Throwable.class)
    public void reserveTimeOut(TbReserve reserve) throws AdapterProxyCreateFail, AdapterException {
        String id = reserve.getId();
        int userId = reserve.getUserID();
        int num = tbReserveMapper.updateStatusTimeout(id, ReserverStatusEnum.RESERVER_OVERTIME.getStatus());

        if (num == 0) {
            _log.error("id:" + id + " 数据不一致性");
//          return;
        }

        TbUserInfo tbuserinfo = tbUserInfoMapper.userInfoById(userId);
        /****** 下发取消息预定单 ****************/
        TbParkspace tbParkspace = configDataCacheInter.queryParkSpace(reserve.getParkID());
        int supplierId = tbParkspace.getSupplierId();
        String parkCode = tbParkspace.getParkCode();
        ReserveAdapter adapterProxy = adapterParkProxyFactory.getReserveAdapter(String.valueOf(supplierId));
        ApReserveOrder apReserveOrder = new ApReserveOrder();
        apReserveOrder.setParkId(parkCode);
        apReserveOrder.setCarNum(reserve.getCarNum());
        apReserveOrder.setStartTime(reserve.getStartTime());
        apReserveOrder.setEndTime(reserve.getEndTime());
        apReserveOrder.setOrderId(id);
        adapterProxy.cancelReserve(apReserveOrder);
        /****** 下发取消息预定单 ****************/

        /****** 向用户发送 预定单超时消息 *************/
        smsInterfaceServiec.reserve_timeout_notice(String.valueOf(tbuserinfo.getTel()));
        /****** 向用户发送 预定单超时 *************/
    }
}
